package com.zzyq.pc.utils;

import java.net.URLDecoder;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;



public class EncodingUtils {

    //如果是URLEncoder处理过的字符串,必有以下的特征
    static Pattern p = Pattern.compile("%[CDEF][0-9A-F]%|%2[1-9]|%2[BCF]|%3[A-F]|%40|%5[B-E]|%60|%7[C-E]"); 
    //如果是URLEncoder处理过的字符串,不会包含以下的字符之外的字符
    static Pattern p2 = Pattern.compile("[^0-9a-zA-Z%_.*+-]");
    
    private static String decodeForGetMethod(String originalString){
        try {
            if(originalString!=null){
                
                int numberOfQuestionMark = StringUtils.countMatches(originalString, "?");
                
                String newString = new String(originalString.getBytes("iso8859-1"), "utf-8");
                
                int numberOfQuestionMarkAfterDecoding = StringUtils.countMatches(newString, "?");
                
                if(numberOfQuestionMark == numberOfQuestionMarkAfterDecoding){
                    originalString = newString;
                } 
                
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        return originalString;
    }
    
    private static String decodeForPostMethod(String originalString){
        try {
            if(originalString !=null){
                Matcher m = p.matcher(originalString);

                if (m.find()) {
                    Matcher m2 = p2.matcher(originalString);
                    if (!m2.find()) {
                        originalString = URLDecoder.decode(originalString, "utf-8");
                    }
                }
            }
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return originalString;
    }
    
    
    public static String  fixUrlParamEncoding(HttpServletRequest request, String originalString){
        String value = originalString;
        
        if (request.getMethod().equalsIgnoreCase("get")) {

            value = decodeForGetMethod(originalString);

        } else if (request.getMethod().equalsIgnoreCase("post")) {

            value = decodeForPostMethod(originalString);
        }

        return value;
    }
    
    public static void fixUrlParamEncoding(HttpServletRequest request, Object bean, List<String> propertyNames){
        Map<String, Object> beanProperties = null;
        
        try {
            beanProperties = PropertyUtils.describe(bean);

            if (request.getMethod().equalsIgnoreCase("get")) {

                for (Map.Entry<String, Object> entry : beanProperties.entrySet()) {
                    if (propertyNames.contains(entry.getKey())) {
                        if (entry.getValue() == null) {
                            continue;
                        }
                        PropertyUtils.setProperty(bean, entry.getKey(), decodeForGetMethod((String)entry.getValue()));

                    }
                }

            } else if (request.getMethod().equalsIgnoreCase("post")) {

                for (Map.Entry<String, Object> entry : beanProperties.entrySet()) {
                    if (propertyNames.contains(entry.getKey())) {
                        if (entry.getValue() == null) {
                            continue;
                        }
                        PropertyUtils.setProperty(bean, entry.getKey(), decodeForPostMethod((String)entry.getValue()));
                    }
                }
            }
        
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

    public static void fixUrlParamEncoding(HttpServletRequest request, Object bean) {

        Map<String, Object> beanProperties = null;

        try {
            beanProperties = PropertyUtils.describe(bean);

            if (request.getMethod().equalsIgnoreCase("get")) {

                for (Map.Entry<String, Object> entry : beanProperties.entrySet()) {
                    if ("class".equals(entry.getKey())) {
                        continue;
                    }
                    if (entry.getValue() == null || !(entry.getValue() instanceof String)) {
                        continue;
                    }
                    PropertyUtils.setProperty(bean, entry.getKey(), decodeForGetMethod((String)entry.getValue()));
                }

            } else if (request.getMethod().equalsIgnoreCase("post")) {

                for (Map.Entry<String, Object> entry : beanProperties.entrySet()) {
                    if ("class".equals(entry.getKey())) {
                        continue;
                    }

                    if (entry.getValue() == null || !(entry.getValue() instanceof String)) {
                        continue;
                    }
                    PropertyUtils.setProperty(bean, entry.getKey(), decodeForPostMethod((String)entry.getValue()));

                }
            }

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}
